/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package io.iec.edp.caf.data.metadata.service;


import io.iec.edp.caf.data.orm.metadata.edm.Schema;

import java.lang.reflect.ParameterizedType;
import java.util.List;
import java.util.Map;

/**
 * 转换Schema扩展接口抽象类
 *
 * @author Vincent Man
 * @date 2021-05-15
 */
public abstract class AbstractSchemaAdapter<T extends Object> implements SchemaAdapter {

    //空参构造
    public AbstractSchemaAdapter() {
    }

    /**
     * 重写spi方法
     *
     * @param obj 转换对象
     * @return Schema
     */
    public Schema convert(Object obj) {
        T cause = this.getT(obj, this.getCauseType());
        return cause != null ? this.convertSchema(cause) : null;
    }

    /**
     * 可扩展获取Schema接口
     * @param schemaMap
     * @return
     */
    public Schema getSchema(Map<String,Object> schemaMap){
        return null;
    }

    /**
     * 可扩展获取Schema 数据接口
     * @param dataMap
     * @return
     */
    public List<Object> getSchemaData(Map<String,Object> dataMap){
        return null;
    }


    /**
     * 获取唯一标识
     * @return
     */
    public String getIdentity(){
        return "";
    }

    /**
     * 获取当前对象泛型<T>
     *
     * @return 泛型
     */
    private Class<T> getCauseType() {
        return (Class<T>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
    }

    /**
     * 将对象转换成指定泛型
     *
     * @param obj  当前对象
     * @param type 当前对象泛型<T>
     * @return 泛型<T>类型对象
     */
    private final <T extends Object> T getT(Object obj, Class<T> type) {
        if (type.isInstance(obj)) {
            return (T) obj;
        }
        return null;
    }


    /**
     * 扩展方法，外部继承AbstractSchemaAdapter实现此方法，方法实现将自定义的类型转换Schema
     *
     * @param entity T类型的对象
     * @return Schema
     */
    public abstract Schema convertSchema(T entity);

}

